package com.idormy.sms.forwarder.utils

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.graphics.Matrix
import android.hardware.camera2.*
import android.media.ImageReader
import android.os.Handler
import android.os.HandlerThread
import android.util.Size
import android.view.Surface
import androidx.core.app.ActivityCompat
import java.io.File
import java.io.FileOutputStream
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

class CameraUtils(private val context: Context) {

    companion object {
        private const val TAG = "CameraUtils"
        private const val IMAGE_WIDTH = 1920
        private const val IMAGE_HEIGHT = 1080
    }

    private var cameraDevice: CameraDevice? = null
    private var captureSession: CameraCaptureSession? = null
    private var imageReader: ImageReader? = null
    private val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
    private var backgroundThread: HandlerThread? = null
    private var backgroundHandler: Handler? = null

    private fun startBackgroundThread() {
        backgroundThread = HandlerThread("CameraBackground").also { it.start() }
        backgroundHandler = Handler(backgroundThread!!.looper)
    }

    private fun stopBackgroundThread() {
        backgroundThread?.quitSafely()
        try {
            // 检查当前线程是否是backgroundThread，避免自我join导致死锁
            if (Thread.currentThread() != backgroundThread) {
                backgroundThread?.join()
            }
            backgroundThread = null
            backgroundHandler = null
        } catch (e: InterruptedException) {
            Log.e(TAG, "Error stopping background thread: ${e.message}")
        }
    }

    suspend fun takePicture(useFrontCamera: Boolean = false): File? = suspendCoroutine { continuation ->
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Log.e(TAG, "Camera permission not granted")
            continuation.resume(null)
            return@suspendCoroutine
        }

        try {
            startBackgroundThread()

            val cameraId = getCameraId(useFrontCamera)
            if (cameraId == null) {
                Log.e(TAG, "No camera found")
                stopBackgroundThread()
                continuation.resume(null)
                return@suspendCoroutine
            }

            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
            val largestSize = map?.getOutputSizes(ImageFormat.JPEG)?.maxByOrNull { it.width * it.height }
                ?: Size(IMAGE_WIDTH, IMAGE_HEIGHT)

            imageReader = ImageReader.newInstance(largestSize.width, largestSize.height, ImageFormat.JPEG, 1)

            val outputFile = File(context.cacheDir, "camera_${System.currentTimeMillis()}.jpg")

            imageReader?.setOnImageAvailableListener({ reader ->
                val image = reader.acquireLatestImage()
                if (image != null) {
                    try {
                        val buffer = image.planes[0].buffer
                        val bytes = ByteArray(buffer.remaining())
                        buffer.get(bytes)

                        // 处理图片旋转
                        val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
                        val rotatedBitmap = rotateBitmap(bitmap, characteristics, useFrontCamera)

                        FileOutputStream(outputFile).use { output ->
                            rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, output)
                        }

                        bitmap.recycle()
                        if (rotatedBitmap != bitmap) {
                            rotatedBitmap.recycle()
                        }

                        Log.d(TAG, "Picture saved: ${outputFile.absolutePath}")
                        closeCamera()
                        stopBackgroundThread()
                        continuation.resume(outputFile)
                    } catch (e: Exception) {
                        Log.e(TAG, "Error saving picture: ${e.message}")
                        closeCamera()
                        stopBackgroundThread()
                        continuation.resumeWithException(e)
                    } finally {
                        image.close()
                    }
                }
            }, backgroundHandler)

            cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
                override fun onOpened(camera: CameraDevice) {
                    cameraDevice = camera
                    createCaptureSession(outputFile, continuation)
                }

                override fun onDisconnected(camera: CameraDevice) {
                    closeCamera()
                    stopBackgroundThread()
                    continuation.resume(null)
                }

                override fun onError(camera: CameraDevice, error: Int) {
                    Log.e(TAG, "Camera error: $error")
                    closeCamera()
                    stopBackgroundThread()
                    continuation.resume(null)
                }
            }, backgroundHandler)

        } catch (e: Exception) {
            Log.e(TAG, "Error taking picture: ${e.message}")
            closeCamera()
            stopBackgroundThread()
            continuation.resumeWithException(e)
        }
    }

    private fun getCameraId(useFrontCamera: Boolean): String? {
        return try {
            val facing = if (useFrontCamera) CameraCharacteristics.LENS_FACING_FRONT else CameraCharacteristics.LENS_FACING_BACK
            cameraManager.cameraIdList.firstOrNull { id ->
                val characteristics = cameraManager.getCameraCharacteristics(id)
                characteristics.get(CameraCharacteristics.LENS_FACING) == facing
            }
        } catch (e: Exception) {
            Log.e(TAG, "Error getting camera ID: ${e.message}")
            null
        }
    }

    private fun createCaptureSession(outputFile: File, continuation: kotlin.coroutines.Continuation<File?>) {
        try {
            val surface = imageReader?.surface ?: return

            cameraDevice?.createCaptureSession(
                listOf(surface),
                object : CameraCaptureSession.StateCallback() {
                    override fun onConfigured(session: CameraCaptureSession) {
                        captureSession = session
                        // 先进行自动对焦和曝光调节，然后再拍照
                        triggerAutoFocusAndExposure()
                    }

                    override fun onConfigureFailed(session: CameraCaptureSession) {
                        Log.e(TAG, "Capture session configuration failed")
                        closeCamera()
                        stopBackgroundThread()
                        continuation.resume(null)
                    }
                },
                backgroundHandler
            )
        } catch (e: Exception) {
            Log.e(TAG, "Error creating capture session: ${e.message}")
            closeCamera()
            stopBackgroundThread()
            continuation.resumeWithException(e)
        }
    }

    private fun triggerAutoFocusAndExposure() {
        try {
            val surface = imageReader?.surface ?: return
            val previewBuilder = cameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
            previewBuilder?.addTarget(surface)
            previewBuilder?.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)
            previewBuilder?.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
            previewBuilder?.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON) // 不使用闪光灯

            // 添加日志：检查AF和AE模式设置
            Log.d(TAG, "Setting AF mode: CONTINUOUS_PICTURE, AE mode: ON (no flash)")

            // 首先启动预览
            captureSession?.setRepeatingRequest(previewBuilder?.build()!!, object : CameraCaptureSession.CaptureCallback() {
                override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
                    val afState = result.get(CaptureResult.CONTROL_AF_STATE)
                    val aeState = result.get(CaptureResult.CONTROL_AE_STATE)
                    Log.d(TAG, "Preview AF State: $afState, AE State: $aeState")
                }
            }, backgroundHandler)
            
            // 等待一段时间后拍照，让AF/AE有时间工作
            Log.d(TAG, "Preview started, waiting for AF/AE to stabilize...")
            
            backgroundHandler?.postDelayed({
                Log.d(TAG, "AF/AE stabilization time reached, starting capture")
                captureSession?.stopRepeating()
                captureStillPicture()
            }, 2000) // 2秒等待时间，让AF/AE稳定

        } catch (e: Exception) {
            Log.e(TAG, "Error in auto focus and exposure: ${e.message}")
            // 如果出错，直接拍照
            captureStillPicture()
        }
    }

    private fun captureStillPicture() {
        try {
            val surface = imageReader?.surface ?: return
            val captureBuilder = cameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
            captureBuilder?.addTarget(surface)
            captureBuilder?.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)
            captureBuilder?.set(CaptureRequest.JPEG_ORIENTATION, 0)

            // 添加日志：检查当前AF和AE状态
            Log.d(TAG, "Starting capture with CONTROL_MODE_AUTO")

            captureSession?.capture(captureBuilder?.build()!!, object : CameraCaptureSession.CaptureCallback() {
                override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
                    val afState = result.get(CaptureResult.CONTROL_AF_STATE)
                    val aeState = result.get(CaptureResult.CONTROL_AE_STATE)
                    Log.d(TAG, "Capture completed - AF State: $afState, AE State: $aeState")
                }
            }, backgroundHandler)
        } catch (e: Exception) {
            Log.e(TAG, "Error capturing picture: ${e.message}")
        }
    }

    private fun rotateBitmap(bitmap: Bitmap, characteristics: CameraCharacteristics, isFrontCamera: Boolean): Bitmap {
        val rotation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0
        val matrix = Matrix()
        matrix.postRotate(rotation.toFloat())
        
        // 前置摄像头需要镜像翻转
        if (isFrontCamera) {
            matrix.postScale(-1f, 1f, bitmap.width / 2f, bitmap.height / 2f)
        }

        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    private fun closeCamera() {
        try {
            captureSession?.close()
            captureSession = null
            cameraDevice?.close()
            cameraDevice = null
            imageReader?.close()
            imageReader = null
        } catch (e: Exception) {
            Log.e(TAG, "Error closing camera: ${e.message}")
        }
    }
}
